import { _decorator } from "cc";
import { BaseComp } from "./BaseComp";
import { EventId, eventMgr } from "../com/EventMgr";
import { layerMgr, ViewLayer } from "../com/LayerMgr";
import { Views } from "../cfg/XlsxDef";
const { ccclass } = _decorator;

/**
 * 界面基类
 */
@ccclass("BaseView")
export abstract class BaseView extends BaseComp {

    /** 所在界面层级 */
    layer: ViewLayer;
    /** 打开界面时的传参 */
    args: any[];
    /** 打开中 */
    isOpen = false;
    /** 关闭界面中 */
    isClosing = false;
    /** 父界面 */
    parent: BaseView;

    /** 界面名 */
    get viewName() { return this.constructor.name; }
    /** 界面路径 */
    get view() { return Views[this.viewName]; }

    /**
     * 打开操作,由LayerMgr调用
     * @param layer 
     * @param args 
     */
    doOpen(layer: ViewLayer, args: any[]) {
        this.layer = layer;
        this.args = args;
        this.isOpen && this.offListeners();
        this.isOpen = true;
        this.onOpen();
        eventMgr.send(EventId.viewOpen, this);
    }

    /**
     * 关闭界面操作,由LayerMgr调用
     */
    doClose() {
        this.isClosing = true;
        this.clearTimerAll();
        this.offAll();
        this.offListeners();
        this.onClose();
        this.node.removeFromParent();
        this.isOpen = false;
        this.isClosing = false;
        eventMgr.send(EventId.viewClose, this);
    }

    /**
     * 关闭界面
     */
    close() {
        layerMgr.close(this.view);
    }

    /**
     * 界面打开后调用
     */
    protected abstract onOpen(): void

    /**
     * 在onClose前或重复onOpen(即界面打开时又执行了onOpen)时调用
     * 取消监听的逻辑一般写在这
     */
    protected abstract offListeners(): void

    /**
     * 界面关闭前调用
     */
    protected abstract onClose(): void

}

declare global {
    /** 事件携带数据 */
    interface EventData {
        [EventId.viewOpen]: BaseView,
        [EventId.viewClose]: BaseView,
    }
}